package com.henu.ocr.service.serviceImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.henu.ocr.entity.Sms;
import com.henu.ocr.entity.SmsIsRead;
import com.henu.ocr.mapper.SmsIsReadMapper;
import com.henu.ocr.mapper.SmsMapper;
import com.henu.ocr.model.SmsDTO;
import com.henu.ocr.service.SmsService;
import com.henu.ocr.util.JWTUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SmsServiceImpl implements SmsService {

    @Autowired private SmsMapper smsMapper;
    @Autowired private SmsIsReadMapper smsIsReadMapper;

    private Integer validateToken(String token) {
        if (token == null || token.isEmpty()) {
            throw new IllegalArgumentException("缺少认证令牌");
        }

        Map<String, String> userInfo = JWTUtil.getUserInfoByToken(token);
        if (userInfo == null || !userInfo.containsKey("userId")) {
            throw new IllegalArgumentException("无效的令牌");
        }

        try {
            String username = userInfo.get("username");
            Integer userId = Integer.parseInt(userInfo.get("userId"));
            if (!JWTUtil.verify(token, username, userId)) {
                throw new IllegalArgumentException("令牌无效或已过期");
            }
            return userId;
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException("非法的用户ID格式");
        }
    }

    private void validateSmsRequest(Sms sms) {
        if (sms.getTitle() == null || sms.getTitle().trim().isEmpty()) {
            throw new IllegalArgumentException("消息标题不能为空");
        }
        if (sms.getContent() == null || sms.getContent().trim().isEmpty()) {
            throw new IllegalArgumentException("消息内容不能为空");
        }
    }

    @Override
    @Transactional
    public void addSms(Sms sms, String token) {
        validateToken(token);
        validateSmsRequest(sms);
        sms.setSendTime(LocalDateTime.now());
        smsMapper.insert(sms);
    }

    @Override
    @Transactional
    public void deleteSms(Integer id, String token) {
        Integer userId = validateToken(token);
        smsMapper.deleteById(id);
        smsIsReadMapper.delete(new QueryWrapper<SmsIsRead>().eq("sms_id", id));
    }

    @Override
    @Transactional
    public void updateSms(Integer id, Sms sms, String token) {
        validateToken(token);
        if (!id.equals(sms.getId())) {
            throw new IllegalArgumentException("路径ID与消息体ID不一致");
        }
        smsMapper.updateById(sms);
    }

    @Override
    public List<SmsDTO> getAllSms(String token) {
        Integer userId = validateToken(token);
        return smsMapper.selectList(null).stream().map(sms -> {
            SmsDTO dto = new SmsDTO();
            BeanUtils.copyProperties(sms, dto);
            SmsIsRead isRead = smsIsReadMapper.selectOne(
                    new QueryWrapper<SmsIsRead>()
                            .eq("sms_id", sms.getId())
                            .eq("user_id", userId)
            );
            dto.setReadTime(isRead != null ? isRead.getReadTime() : null);
            return dto;
        }).collect(Collectors.toList());
    }

    @Override
    public SmsDTO getSmsById(Integer id, String token) {
        Integer userId = validateToken(token);
        Sms sms = smsMapper.selectById(id);
        if (sms == null) return null;

        SmsDTO dto = new SmsDTO();
        BeanUtils.copyProperties(sms, dto);
        SmsIsRead isRead = smsIsReadMapper.selectOne(
                new QueryWrapper<SmsIsRead>()
                        .eq("sms_id", id)
                        .eq("user_id", userId)
        );
        dto.setReadTime(isRead != null ? isRead.getReadTime() : null);
        return dto;
    }

    @Override
    @Transactional
    public void markAsRead(Integer smsId, String token) {
        Integer userId = validateToken(token);
        SmsIsRead record = new SmsIsRead();
        record.setSmsId(smsId);
        record.setUserId(userId);
        record.setReadTime(LocalDateTime.now());

        int updated = smsIsReadMapper.update(record,
                new UpdateWrapper<SmsIsRead>()
                        .eq("sms_id", smsId)
                        .eq("user_id", userId)
        );

        if (updated == 0) {
            smsIsReadMapper.insert(record);
        }
    }
}